﻿
namespace n_TNodeSet
{
using System;
using System.Drawing;
using System.Windows.Forms;
using n_MusicFunction;
using n_MusicForm;
using n_Node;
using n_OS;
using n_SG;
using n_MusicPanel;

//============================================================
//乐谱列表
public class TNodeSet
{
	public delegate void D_SelChanged();
	public static D_SelChanged d_SelChanged;
	
	public TNode[] TNodeList;
	public int TNodeListLength;
	public int PlayIndex;
	
	//播放音量
	public int Volume;
	
	static TNode v_SelectedTNode;
	public static TNode SelectedTNode
	{
		get {
			return v_SelectedTNode;
		}
		set {
			v_SelectedTNode = value;
			if( d_SelChanged != null ) {
				d_SelChanged();
			}
		}
	}
	
	public int NumberPerLine;
	
	public int Channel;
	
	//构造函数
	public TNodeSet( int i )
	{
		TNodeList = new TNode[ 500 ];
		TNodeListLength = 0;
		
		Channel = i;
		
		SelectedTNode = null;
		
		NumberPerLine = 7;
		
		//TNode.Percent = 128;
		TNode.PiN = 4;
		TNode.Fen = 4;
		
		PlayIndex = -1;
	}
	
	//保存音乐文件
	public string Save()
	{
		string s = "";
		
		//时值单位和移调
		s += "254," + TNode.DoEqual + "," + TNode.TimeTick + ",";
		
		//节拍
		s += "253," + (TNode.Fen*16+TNode.PiN) + ",";
		
		//音量
		s += "127," + Volume + ",";
		
		//音色
		s += "126," + 0 + ",";
		
		for( int i = 0; i < TNodeListLength; ++i ) {
			s += (TNodeList[i].LianYin? (0x80+TNodeList[i].Tone): TNodeList[i].Tone) + "," + TNodeList[i].Time + ",";
		}
		return s;
	}
	
	//打开音乐文件
	public void Open( string Text, bool Old )
	{
		string[] sp = Text.TrimEnd( ',' ).Split( ',' );
		
		Clear();
		
		//格式化
		for( int i = 0; i < sp.Length; ++i ) {
			sp[i] = sp[i].Trim( '\n' );
			if( sp[i].StartsWith( "0x" ) ) {
				sp[i] = (int.Parse( sp[i].Remove( 0, 2 ), System.Globalization.NumberStyles.HexNumber )).ToString();
			}
		}
		//解码音乐数据
		for( int i = 0; i < sp.Length; ++i ) {
			int Tone = int.Parse( sp[i] );
			
			//时值单位和移调
			if( Tone == 254 ) {
				TNode.DoEqual = int.Parse( sp[i+1] );
				TNode.TimeTick = int.Parse( sp[i+2] );
				i += 2;
			}
			//节拍
			else if( Tone == 253 ) {
				int mn = int.Parse( sp[i+1] );
				TNode.PiN = mn % 16;
				TNode.Fen = mn / 16;
				i++;
			}
			//音量
			else if( Tone == 127 ) {
				Volume = int.Parse( sp[i+1] );
				i++;
			}
			//音色
			else if( Tone == 126 ) {
				//TNode.Volume = int.Parse( sp[i+1] );
				i++;
			}
			else {
				int Time = int.Parse( sp[i+1] );
				
				
				if( Old && Tone != 0 ) {
					Tone -= 6;
				}
				
				AddEnd( Tone & 0x7F, Time, (Tone & 0x80) != 0 );
				i++;
			}
		}
	}
	
	//清除
	public void Clear()
	{
		TNodeListLength = 0;
		SelectedTNode = null;
	}
	
	//添加一个音节节点
	public void Add( int ToneIndex, int Time )
	{
		for( int i = 0; i < TNodeListLength; ++i ) {
			if( TNodeList[i] == SelectedTNode ) {
				TNodeListLength++;
				for( int n = TNodeListLength - 2; n > i; --n ) {
					TNodeList[n + 1] = TNodeList[n];
				}
				TNodeList[i+1] = new TNode( this, ToneIndex, Time );
				SelectedTNode = TNodeList[i+1];
				return;
			}
		}
	}
	
	//添加一个音节节点
	public void AddEnd( int ToneIndex, int Time, bool ly )
	{
		TNodeList[TNodeListLength] = new TNode( this, ToneIndex, Time );
		TNodeList[TNodeListLength].LianYin = ly;
		TNodeListLength++;
	}
	
	//删除选中的音符
	public void Delete()
	{
		for( int i = 0; i < TNodeListLength; ++i ) {
			if( TNodeList[i] == SelectedTNode ) {
				for( int j = i; j < TNodeListLength - 1; ++j ) {
					TNodeList[j] = TNodeList[j + 1];
				}
				TNodeListLength--;
				if( i >= TNodeListLength ) {
					SelectedTNode = null;
				}
				else {
					SelectedTNode = TNodeList[i];
				}
				return;
			}
		}
	}
	
	//------------------------------------------------------------------
	
	public int CX;
	int CI;
	int CY;
	int Percent;
	int cent;
	int JNumber;
	bool isfirst;
	bool isfirstclm;
	public bool isPerNoteEnd;
	
	public void StartRefreshSize()
	{
		CI = 0;
		CX = 20;
		
		CY = 50 + TNode.PerHeight * Channel;
		
		isfirst = true;
		isfirstclm = true;
		
		//每个小节的分数
		Percent = TNode.GetPercent();  //32 * 4
		//当前音符所在的小节的分数
		cent = 0;
		
		n_Main.Program.MusicTimeWarning( "" );
		
		JNumber = 0;
	}
	
	//重新计算各个音节的坐标和尺寸
	public bool RefreshSizeOk()
	{
		if( CI < TNodeListLength ) {
			TNodeList[CI].TimeError = false;
			TNodeList[CI].Cent = cent;
			int w = TNode.PerWidth * MusicFunction.NumberOfTime( TNodeList[CI].Time );
			cent += TNodeList[CI].Time;
			
			if( cent > Percent ) {
				n_Main.Program.MusicTimeWarning( "第" + CI + "个音符时值超出了一个小节, 如果需要跨小节演奏同一音符, 请拆分成两个音符, 并设置好第一个音的连音标志" );
				TNodeList[CI].TimeError = true;
				cent -= Percent;
				w += TNode.PerWidth;
				
				++JNumber;
				if( JNumber % NumberPerLine == 0 ) {
					CY += TNode.PerHeight * 2 + 20;
					CX = 20;
				}
			}
			TNodeList[CI].isFirst = isfirst;
			TNodeList[CI].isEnd = false;
			TNodeList[CI].isFirstColumn = isfirstclm;
			isfirst = false;
			isfirstclm = false;
			TNodeList[CI].X = CX;
			TNodeList[CI].Y = CY;
			TNodeList[CI].Width = w;
			TNodeList[CI].Height = TNode.PerHeight;
			CX += w;
			
			if( cent >= Percent ) {
				cent -= Percent;
				CX += TNode.PerWidth;
				++JNumber;
				TNodeList[CI].isEnd = true;
				isPerNoteEnd = true;
				isfirst = true;
				
				if( JNumber % NumberPerLine == 0 ) {
					CY += TNode.PerHeight * 2 + 20;
					CX = 20;
					isfirstclm = true;
				}
			}
			else {
				isPerNoteEnd = false;
			}
		}
		
		++CI;
		if( CI >= TNodeListLength ) {
			isPerNoteEnd = true;
			return true;
		}
		return false;
	}
	
	//------------------------------------------------------------------
	
	//鼠标按下事件
	public TNode MouseDown( PointF p )
	{
		TNode temp = null;
		for( int i = 0; i < TNodeListLength; ++i ) {
			bool o = TNodeList[i].MouseDown( p );
			if( o ) {
				temp = TNodeList[i];
			}
		}
		return temp;
	}
	
	//鼠标松开事件
	public void MouseUp( PointF p )
	{
		for( int i = 0; i < TNodeListLength; ++i ) {
			TNodeList[i].MouseUp( p );
		}
	}
	
	//鼠标移动事件
	public void MouseMove( PointF p )
	{
		for( int i = 0; i < TNodeListLength; ++i ) {
			TNodeList[i].MouseMove( p );
		}
	}
	
	//绘制各个音节
	public void Draw()
	{
		TNode LastLianYinNode = null;
		
		for( int i = 0; i < TNodeListLength; ++i ) {
			
			if( TNodeList[i].LianYin && i != TNodeListLength - 1 ) {
				if( LastLianYinNode == null ) {
					LastLianYinNode = TNodeList[i];
				}
			}
			else {
				if( LastLianYinNode != null ) {
					
					//绘制连音线
					//SG.MLine.Draw( Color.Black, 1, LastLianYinNode.X + TNode.PerWidth/2, LastLianYinNode.Y + 5, TNodeList[i].X + TNode.PerWidth/2, TNodeList[i].Y + 5 );
					
					if( TNodeList[i].isFirstColumn ) {
						
						int xx1 = LastLianYinNode.X + TNode.PerWidth/2;
						int yy1 = LastLianYinNode.Y + 7;
						int xx2 = xx1 + 20;
						int yy2 = yy1 - 4;
						SG.g.DrawBezier( Pens.Black,
		            		xx1, yy1,
		             		xx1 + 3, yy1 - 4,
		             		xx2 - 5, yy2,
		             		xx2, yy2
							);
						
						xx2 = TNodeList[i].X + TNode.PerWidth/2;
						yy2 = TNodeList[i].Y + 7;
						xx1 = xx2 - 20;
						yy1 = yy2 - 4;
						SG.g.DrawBezier( Pens.Black,
		            		xx1, yy1,
		             		xx1 + 5, yy1,
		             		xx2 - 3, yy2 - 4,
		             		xx2, yy2
							);
					}
					else {
						int xx1 = LastLianYinNode.X + TNode.PerWidth/2;
						int yy1 = LastLianYinNode.Y + 7;
						int xx2 = TNodeList[i].X + TNode.PerWidth/2;
						int yy2 = TNodeList[i].Y + 7;
						SG.g.DrawBezier( Pens.Black,
		            		xx1, yy1,
		             		xx1 + 3, yy1 - 4,
		             		xx2 - 3, yy2 - 4,
		             		xx2, yy2
							);
					}
					
					
					LastLianYinNode = null;
				}
			}
			TNodeList[i].Draw( false, i == PlayIndex );
		}
		if( SelectedTNode != null ) {
			SelectedTNode.Draw( true, false );
		}
	}
}
}




